package org.greenwire.islandharvester.helper;

import java.util.Timer;
import java.util.TimerTask;

import net.sf.json.JSONObject;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.greenwire.islandharvester.domain.Container;
import org.greenwire.islandharvester.domain.Dock;
import org.greenwire.islandharvester.domain.Harvestable;
import org.greenwire.islandharvester.domain.Island;
import org.greenwire.islandharvester.result.Result;

import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.google.gson.Gson;

public class HarvestHelper {
	
	private final Log logger = LogFactory.getLog(HarvestHelper.class);
	
	private WebClient client;
	
	public HarvestHelper(WebClient client){
		this.client = client;
	}
	
	public boolean startHarvest(){
		logger.info("Start harvesting.");
		
		HtmlPage mainPage;
		try {
			mainPage = (HtmlPage)client.getPage("http://island.hapyfish.com/api/initisland?time=1275028338296");
		} catch (Exception e) {
			logger.error(e.getMessage() ,e);
			return false;
		}
		
		String jsonResult = mainPage.getWebResponse().getContentAsString();
		JSONObject jsonObject = JSONObject.fromObject(jsonResult);
		Gson g = new Gson(); 
		
		// 处理码头船只
		Dock dock = g.fromJson(jsonObject.getString("dockVo"), Dock.class);
		doHarvest(dock);
		
		// 处理建筑物
		Island island = g.fromJson(jsonObject.getString("islandVo"), Island.class);
		doHarvest(island);	
		
		logger.info("All harvest job DONE!");
		
		return true;
	}
	
	/**
	 * 进行收获操作
	 * @param container
	 */
	private void doHarvest(Container container) {
		for (Harvestable harvestable : container.getHarvestables()) {
			if (harvestable.isHarvestable()) { // 有可能是树、装饰
				if (harvestable.available4HarvestImmediately()) {
					harvestImmediately(harvestable, container.getOwnerUid());
				} else if (harvestable.available4HarvestLater()){ // 也有可能是无人光顾，所以不能直接 else
					harvestLater(harvestable, container.getOwnerUid());
				}
			}
		}
	}
	
	/**
	 * 立即进行收获
	 * @param harvestable
	 * @param ownerUid
	 */
	private void harvestImmediately(Harvestable harvestable, String ownerUid){
		HtmlPage resultPage;
		try {
			resultPage = (HtmlPage) client.getPage(harvestable.getHarvestUrl(ownerUid));
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			return;
		}
		Result result = harvestable.parseResult(resultPage.getWebResponse().getContentAsString());
		logger.info("Harvesting shit, type [" + harvestable.getType() + "], id [" + harvestable.getId() + "]");
		logger.info(result.getResultStr());
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			logger.error(e.getMessage(), e);
		}
	}
	
	/**
	 * 安排延迟任务进行收获
	 * @param harvestable
	 * @param ownerUid
	 */
	private void harvestLater(final Harvestable harvestable, final String ownerUid){	
		
		// 已经安排了任务就不再重复安排
		if(FilePersistentHelper.alreadyScheduled(ownerUid, harvestable)){
			logger.info("Task already been scheduled for id [" + harvestable.getId() + "], type [" + harvestable.getType() + "], abort!");
			return;
		}
		
		long delay;
		try{
			delay = Long.parseLong(harvestable.getNextAvailableTime()) * 1000;
		} catch (NumberFormatException nfe){
			logger.error("Illegal time format : " + harvestable.getNextAvailableTime() + ", abort scheduling!");
			return;
		}
		
		delay = delay < 0 ? 0 - delay : delay;
		
		logger.info("Scheduling a latter harvest job for id [" + harvestable.getId() + "], type [" + harvestable.getType() + 
				"] delay for " + delay / 1000 + " seconds!");
		
		Timer a = new Timer(true);
		a.schedule(new TimerTask(){
			
			private Log logger = LogFactory.getLog("Timer task");
			
			@Override
			public void run() {
				logger.info("Scheduled task started! id [" + harvestable.getId() + "], type [" + harvestable.getType() + "]!");
				harvestImmediately(harvestable, ownerUid);
				// FIXME 这里可能有并发问题，恐怕需要使用数据库做持久化
				FilePersistentHelper.removeId(ownerUid, harvestable.getType(), harvestable.getId());
			}			
			
		}, delay + 5);
		
		FilePersistentHelper.saveHarvestableId(ownerUid, harvestable.getType(), harvestable.getId());
	}
}
